package com.liangtian.mdm.base.utils;

import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Value;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.io.ByteArrayOutputStream;
import java.security.Key;

/**
 * <p>Encoding    :  UTF-8</p>
 * <p>Package Name: com.liangtian.mdm.base.utils </p>
 * <p>Project Name: dm </p>
 * <p>Copyright   :  Copyright(c) 2016 石化盈科信息技术有限责任公司 </p>
 * <p>Created Time: 2016-05-26 11:17</p>
 * <p>Description : 解密工具</p>
 *
 * @author : beamzhang
 * @version :  1.0
 */
public class Decoder {

    @Value("${CIPHER_ALGORITHM}")
    private static String CIPHER_ALGORITHM;

    /**
     * 构造函数.
     */
    public Decoder() {
    }

    /**
     * 将16进制字符串转换成字节数组.
     *
     * @param strHex 16进制字符串
     * @return 字节数组.
     */
    public static byte[] hexStringToByteArray(String strHex) {
        byte[] theResult = null;
        byte[] byteArr = new byte[strHex.length()/2];
        for (int i = 0; i < byteArr.length; i++) {
            byteArr[i] = (byte) Integer.parseInt(strHex.substring(i*2, i*2 + 2), 16);
        }
        theResult = byteArr;
        return theResult;
    }

    /**
     * 解密数据(对称解密)经http传输使用
     *
     * @param data 待解密数据
     * @param key  密钥
     * @return 解密后的数据
     */
    public static String symmetricDecrypto(String data, String key) throws Exception {
        Key k = Encoder.toKey(Base64.decodeBase64(key));
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, k);                           //初始化Cipher对象，设置为解密模式
        return new String(cipher.doFinal(Base64.decodeBase64(data)));  //执行解密操作
    }


    /**
     * 对称解密方法
     *
     * @param byteSource 需要解密的数据
     * @return 经过解密的数据
     * @throws Exception
     */
    public static byte[] symmetricDecrypto(byte[] byteSource) throws Exception {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            int mode = Cipher.DECRYPT_MODE;
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            byte[] keyData = {9, 1, 3, 7, 2, 1, 2, 0};
            DESKeySpec keySpec = new DESKeySpec(keyData);
            Key key = keyFactory.generateSecret(keySpec);
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(mode, key);
            int blockSize = cipher.getBlockSize();
            int position = 0;
            int length = byteSource.length;
            boolean more = true;
            while (more) {
                if (position + blockSize <= length) {
                    baos.write(cipher.update(byteSource, position, blockSize));
                    position += blockSize;
                } else {
                    more = false;
                }
            }
            if (position < length) {
                baos.write(cipher.doFinal(byteSource, position, length
                        - position));
            } else {
                baos.write(cipher.doFinal());
            }
            return baos.toByteArray();
        } catch (Exception e) {
            throw e;
        } finally {
            baos.close();
        }
    }

    public static String symmetricDecrypto(String strSource) throws Exception {
        byte[] byteSource = hexStringToByteArray(strSource);
        byte[] byteArr = symmetricDecrypto(byteSource);
        String result = new String(byteArr);
        return result;
    }
}
